package com.init.bootframe.config.Filter;

import com.init.bootframe.util.TmompConstant;
import com.init.bootframe.util.TmompEncryptUtil;
import com.init.bootframe.util.TmompUser;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import javax.servlet.*;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;

public class MyFilter implements Filter {

    private static Logger logger = LoggerFactory.getLogger(MyFilter.class);

    @Override
    public void init(FilterConfig filterConfig) throws ServletException {
    }
    // 无需加解密
    private static String[] AES_FILTER_METHODS = new String[] {"/upload", "\\upload", "/ueditor", "/web/"};

    // 无需登录
    private static String[] LOGIN_FILTER_METHODS = new String[] {"/upload", "\\upload","login", "/web/", "/webs/"};

    @Override
    public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
        HttpServletRequest request = (HttpServletRequest) servletRequest;
        HttpServletResponse response = (HttpServletResponse) servletResponse;
        String requestUrl = request.getServletPath();

        response.setCharacterEncoding(TmompConstant.BaseDataConstant.INPUT_STREAM_READER_ENCODING);
        response.setContentType("text/html;charset=" + TmompConstant.BaseDataConstant.INPUT_STREAM_READER_ENCODING);

        if (requestUrl.contains(".html")){// 页面过滤
            filterChain.doFilter(request, response);
        }else if (requestUrl.contains("/main/")) {
            filterChain.doFilter(request, response); // 静态资源过滤
        } else {
            if(verifyLoginEffectiveRequest(requestUrl)) { //判断是否需要登录
                // 判断当前用户是否登录
                String userId = TmompUser.getCurrentUserId();
                if (null != userId && !"".equals(userId)) { //登录成功
                }else{ // 暂未登录 跳转登录界面
                    response.setIntHeader("REQUIRES_AUTH", 1);
                    response.setHeader("REQUIRES_AUTH_URL", request.getContextPath() + "/login.html");
                    return;
                }
            }
            if (verifyAESEffectiveRequest(requestUrl)) {
                logger.debug("requestUrl:"+requestUrl);
                // 防止流读取一次后就没有了, 所以需要将流继续写出去 读取参数解密处理
                ServletRequest requestWrapper = new BodyReaderHttpServletRequestWrapper(request);
                // 返回值代理类
                BodyReaderHttpServletResponseWrapper wrapperResponse = new BodyReaderHttpServletResponseWrapper(response);
                wrapperResponse.setCharacterEncoding(TmompConstant.BaseDataConstant.INPUT_STREAM_READER_ENCODING);
                wrapperResponse.setContentType("text/html;charset=" + TmompConstant.BaseDataConstant.INPUT_STREAM_READER_ENCODING);

                filterChain.doFilter(requestWrapper, wrapperResponse);
                wrapperResponseAes(wrapperResponse, response);
            }else{ // 无需加解密处理
                filterChain.doFilter(request, response);
            }
        }
    }

    /**
     * 处理返回值
     * @param wrapperResponse
     * @param response
     * @throws IOException
     */
    private void wrapperResponseAes(BodyReaderHttpServletResponseWrapper wrapperResponse, HttpServletResponse response) throws IOException {
        // 处理返回值
        byte[] content = wrapperResponse.getContent();//获取返回值
        // 判断返回是否有值
        if(content.length > 0) {
            String str = new String(content, "UTF-8");
            String ciphertext = null;
            try {
                ciphertext = "\"" + TmompEncryptUtil.aesEncrypt(str) + "\"";

            }
            catch (Exception e) {
                e.printStackTrace();
                logger.info("---------------Filter处理加密出参异常-----------------");
            }finally {
                logger.debug("加密后返回值:" + ciphertext);
                //把返回值输出到客户端
                ServletOutputStream out = response.getOutputStream();
                out.write(ciphertext.getBytes());
                out.flush();
                out.close();
            }
        }
    }

    @Override
    public void destroy() {
    }

    /**
     * 判断当前请求是否需要处理
     * @param url
     * @return
     */
    private boolean verifyAESEffectiveRequest(String url) {
        // 部分方法不做过滤处理
        for (int i = 0; i < AES_FILTER_METHODS.length; i++) {
            // 排除拦截以外方法
            if (url.contains(AES_FILTER_METHODS[i])) {
                return false;
            }
        }
        return true;
    }

    /**
     * 是否登录判断
     * @param url
     * @return
     */
    private boolean verifyLoginEffectiveRequest(String url) {
        // 部分方法不做过滤处理
        for (int i = 0; i < LOGIN_FILTER_METHODS.length; i++) {
            // 排除拦截以外方法
            if (url.contains(LOGIN_FILTER_METHODS[i])) {
                return false;
            }
        }
        return true;
    }
}
